home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_10_11
/
1011125a
< prev
next >
Wrap
Text File
|
1992-09-07
|
20KB
|
424 lines
echo Extracting splot.c...
cat <<WRAP_EOF >splot.c
/**************************************************************************
* SPLOT - Builds a screen plot of data points and curves.
* Creates HP LaserJet .PCL and PostScript .PS files for printing.
*
* *pstfil & *hpfil - output files (may be NULL if not needed)
* xdivs & ydivs - number of X and Y axis divisions
* xgrid & ygrid - grid line flags (1 for lines, 0 for no lines)
* nplots - number of curves (each has 0 or more symbol points)
* *x[] & *y[] - Arrays of pointers to arrays of X and Y values
* npts_pnts[] - array of number of symbol points for each curve
* npts_tot[] - array of number of total points for each curve
* title - character array for graph title
* xaxis,yaxis - character arrays for X and Y axis labels
* *msg[] - pointers to strings to appear in a message box
* nmsg[] - number of strings in message box (0 for no box) and
* X and Y coordinates of beginning of first string
* (640 x 480 screen cordinates)
*
* For "curve" i of the nplots "curves" the first npts_pnts[i] points are
* plotted with symbols only. The remaining points up to npts_tot[i-1] are
* plotted with connecting lines but no symbols. The number of either
* symbols or connecting lines, but not both, may be 0.
**************************************************************************/
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <stdarg.h>
#include <graphics.h>
#include aalloc.h>
#define CORE 0 /* = 1 for coreleft() report after initgraph() */
#define YTEXT YD+19. /* Y cordinate for xaxis labeling */
/* XL=X axis start, XR=X axis end, YU=Y axis upper, YD=Y axis lower. */
double XL=72. ,XR=619. ,YU=29. ,YD=441. ,YDM=479.;
FILE *postfile; /* File scope PostScript output file */
int DIRECTION; /* 0 for horizontal text, 1 for vertical */
int YAXOFF; /* Offset for Y axis title */
int GraphDriver; /* The Graphics device driver */
int GraphMode; /* The Graphics mode value */
int ErrorCode; /* Reports any graphics errors */
/* Function prototypes */
void linscale (double xmin,double xmax,int n,double *xminp,double *xmaxp,
doulle *dist);
void outlin(double x1, double y1, double x2, double y2);
void box(double x1,double y1,double x2,double y2);
void linaxis(int axis,double start,double dist,int divs, int grids, double dotsperdiv,
int ticksize);
void changetextstyle(int direction, int charsize);
void formx(char* str,double x, int *prec, int *typ, int kon);
void outtxt(double x, double y, int horiz, int vert, char *txt);
void symbol(double x,double y, int num);
void msgbox(char *msg[], int *nmsg);
void hpltit(FILE *hpfile);
void splot(FILE *pstfil, FILE *hpfile, int xdivs, int ydivs, int xgrid,
int ygrid, int nplots, double *x[], double *y[], int *npts_pnts,
int *npts_tot, char *title, char *xaxis, char *yaxis,char *msg[], int *nmsg)
{ double xdotsprdiv, ydotsprdiv,xstart, xstop, ystart, ystop,xdata, ydata,
xdist, ydist, xlast, ylast, xscale, yscale, limits[4];
unsigned long core;
int i, j, ticksize;
#if CORE==1
char nar[90];
#endif
core=(unsigned long)coreleft();
if (core<16000L)
{ fprintf(stderr,"Only %lu core left at entry to PLOTS. About 16000 needed.\n",core);
fprintf(stderr,"^C to stop and use COMPACT or LARGE model, any other key to procede\n");
i=getch(); if (i==3) exit(1);
}
postfile=pstfil; ticksize = 5; YAXOFF=0;
fprintf(postfile,"%%!PS-Adobe-2.0 EPSF-1.2\n%%%%BoundingBox: 0 0 612 792\n");
fprintf(postfile,"/cntrj{dup stringwidth pop 2 div neg 0 rmoveto} bind def\n");
fprintf(postfile,"/rtj{dup stringwidth pop neg 0 rmoveto} bind def\n");
fprintf(postfile,"552 80 translate 90 rotate \n");
/* Calculate dotsperdiv and adjust YU and XR to an integral multiple */
xdotsprdiv = (int)((XR - XL) / xdivs); ydotsprdiv = (int)((YD - YU) / ydivs);
XR=XL+(int)(xdivs*xdotsprdiv); YU=YD-(int)(ydivs*ydotsprdiv);
/* Determine the upper and lower limits of the data. */
limits[0] = limits[2] = 9.99e+99; limits[1] = limits[3] = -9.99e+99;
for (i=0; i<nplots; ++i) for (j=0; j<npts_tot[i]; ++j)
{ if (x[i][j]<limits[0]) limits[0]=x[i][j]; if (x[i][j]>limits[1]) limits[1]=x[i][j];
if (y[i][j]<limits[2]) limits[2]=y[i][j]; if (y[i][j]>limits[3]) limits[3]=y[i][j];
}
/* initialize graphics (hi-res), draw and label graph */
GraphDriver=(int)DETECT; /* Request auto-detection */
initgraph (&GraphDriver, &GraphMode,"");
ErrorCode=graphresult(); /* Read result of initialization*/
if (ErrorCode!=(int)grOk) /* Error occured during init */
{ fprintf(stderr,"Graphics System Error: %s\n",grapherrormsg(ErrorCode));
exit(1);
}
if (GraphDriver!= (int)VGA)
{ fprintf(stderr,"The screen plot program requires a VGA monitor\n");
closegraph(); exit(1);
}
changetextstyle(0,5); /* Text size and style for axis numbers */
#if CORE==1
sprintf(nar,"After graphics initialization there is %lu core left",
(unsigned long)coreleft());
outtxt(0.,15.,0,0,nar);
outtxt(0.,30.,0,0,"At least 1000 is needed. Hit enter to procede."); getch();
#endif
/* box(0.,0.,639.,479.); */ /* Optional bounding box for checking layout. */
box(XL, YU, XR, YD); /* Draw bounding box */
/* do linear plot scaling */
linscale (limits[2],limits[3],ydivs,&ystart,&ystop,&ydist);
linscale (limits[0],limits[1],xdivs,&xstart,&xstop,&xdist);
/* draw and label axes */
linaxis (0,ystart,ydist,ydivs,ygrid,ydotsprdiv,ticksize);
linaxis (1,xstart,xdist,xdivs,xgrid,xdotsprdiv,ticksize);
changetextstyle(0,6); outtxt(325.,12.,1,0,title);
changetextstyle(0,5); outtxt((XL+XR)/2.,YDM-2.,1,0,xaxis);
changetextstyle(1,5);
outtxt(XL-10.-(double)YAXOFF,(YU+YD)/2.,2,1,yaxis);
changetextstyle(0,5);
xscale=xdotsprdiv/xdist; yscale=ydotsprdiv/ydist;
/* Plot the data points */
for (i=0; i<nplots; ++i) for (j=0; j<npts_pnts[i]; ++j)
{ xdata=(int)(XL+(x[i][j]-xstart)*xscale); ydata=(int)(YD-(y[i][j]-ystart)*yscale);
symbol(xdata,ydata,i);
}
/* Plot the curves */
for (i=0; i<nplots; ++i) for (j=npts_pnts[i]; j<npts_tot[i]; ++j)
{ xdata=XL+(x[i][j]-xstart)*xscale; ydata=YD-(y[i][j]-ystart)*yscale;
if (j==npts_pnts[i]) { xlast=xdata; ylast=ydata; continue; }
outlin(xlast,ylast,xdata,ydata); xlast=xdata; ylast=ydata;
}
if (nmsg[0]) msgbox(msg,nmsg);
fprintf(postfile," showpage\n%c\n",4);
if (hpfile!=NULL) hpltit(hpfile);
(void)getch(); /* Hold the graph on screen till a key is pressed. */
closegraph();
(void)fclose(postfile);
(void)fclose(hpfile);
} /********************* end function plots(........) **************/
/*************************************************************************
* LINSCALE - Define linear scale limits - fixed interval.
* Given estimated maximum and minimum values and a requested number of
* intervals, adjust the extrema to encompass the same number of equal
* intervals of size dist, such that they are "nice" values for a plot.
*
* Input: xmin - minimum value.
* xmax - maximum value.
* n - number of data intervals required.
* Output: xminp - adjusted minimum value.
* xmaxp - adjusted maximum value.
* dist - data interval size.
*
* xmin, xmax, and n are not modified.
*
* vint(*) is an array of acceptable values for dist (times an integer power of 10).
*
* Adapted from C. R. Lewart, Comm. ACM, algorithm 463 (1972).
************************************************************************/
void linscale (double xmin, double xmax, int n, double *xminp,
double *xmaxp, double *dist)
{ int i, m1, m2, nal, np, nx, nvnt;
double a, b, fm1, fm2;
double del=2.0e-9, vint[]={1.,2.,4.,5.,6.,8